def calculate_speed(time_list,lat_list,lon_list,ele_list):
    if len(time_list)==len(lat_list) and len(time_list)==len(lon_list) and len(time_list)==len(ele_list):
        pass
    else:
        return 
    
    df = pd.DataFrame({'time': time_list, 'lat': lat_list, 'lon': lon_list, 'ele': ele_list})
    columns = df.columns.tolist()

    df['r'] = 6371393+df['ele'] # radius of the Earth in meters

    df['theta'] = np.deg2rad(df['lon'])
    df['phi'] = np.deg2rad(df['lat'])
    df['theta2']=df['theta'].shift()
    df['phi2']=df['phi'].shift()
    
    df['arclength'] = df['r'] * np.arccos(np.cos(df['phi']) * np.cos(df['phi2']) * np.cos(df['theta2']-df['theta']) + np.sin(df['phi'])*np.sin(df['phi2']))
    
    elapsed_time_list=[]
    stamp_list=[]
    speed_list=[]
    
    stamp_same_list=[]
    same_flag=0
    enable_flag=0
    exit_same_list=[]
    for i in range(len(time_list)):
        try:
            stamp_list.append(time.mktime(time.strptime(time_list[i], "%Y-%m-%d %H:%M:%S")))
            enable_flag=1
            if i>0 and enable_flag==1:
                if stamp_list[i]>stamp_list[i-1]:
                    elapsed_time_list.append(stamp_list[i]-stamp_list[i-1]) 
                    if same_flag==1:
                        same_flag=0
                        exit_same_list.append(i)
                else:
                    if same_flag==0:
                        stamp_same_list.append(i)
                    same_flag=1
                    elapsed_time_list.append(0.0)
            else:
                elapsed_time_list.append(None)
        except:
            if enable_flag==0:
                elapsed_time_list.append(None)
            else:
                if same_flag==0:
                    stamp_same_list.append(i)
                same_flag=1
                elapsed_time_list.append(0.0)
                
    if len(stamp_same_list)>len(exit_same_list):
        exit_same_list.append(0)  

    j=0
    displacement=0.0
    displacement_time=0.0
    end_displacement=0.0
    same_flag=0
    end_elapsed_time=0.0
    stamp_same_in_1st_flag=0
    
    if len(stamp_same_list)==0:
        for i in range(len(elapsed_time_list)):
            try:
                try:
                    speed_list.append((df['arclength'][i]+df['arclength'][i+1])/ (elapsed_time_list[i]+elapsed_time_list[i+1]))  # km/h
                except:
                    speed_list.append(df['arclength'][i]/ elapsed_time_list[i])  # m/s
            except:
                speed_list.append(None)
    else:  
        for i in range(len(elapsed_time_list)):
            try:
                if i>0:
                    try:
                        if i==stamp_same_list[j]-1:
                            same_flag=1
                                
                        if stamp_same_list[0]==1 and stamp_same_in_1st_flag==0:
                            stamp_same_in_1st_flag=1
                            same_flag=1
                        
                    except:
                        pass
       
                    if same_flag==0:
                        try:
                            speed_list.append((df['arclength'][i]+df['arclength'][i+1])/ (elapsed_time_list[i]+elapsed_time_list[i+1]))  # m/s
                        except:
                            speed_list.append(df['arclength'][i]/ elapsed_time_list[i])  # m/s
                    else:   
                        try:
                            displacement=displacement+df['arclength'][i]
                        except:
                            displacement=displacement+0.0
                        
                        try:
                            displacement_time=displacement_time+elapsed_time_list[i]
                        except:
                            displacement_time=displacement_time+0.0
                        
    
                        if j==len(stamp_same_list)-1 and exit_same_list[j]==0:
                            if end_elapsed_time==0.0:
                                end_elapsed_time=elapsed_time_list[i]                                
                            end_displacement=end_displacement+df['arclength'][i]
                            if end_elapsed_time>0.0:
                                speed_list.append(end_displacement/end_elapsed_time)
                            else:
                                speed_list.append(end_displacement/1.0)
                        else:
                            speed_list.append(None)
    
                        if i==exit_same_list[j]: 
                            avg_speed=displacement/displacement_time
                            for k in range(stamp_same_list[j]-1,i+1):
                                speed_list[k]=avg_speed       
                            j=j+1
                            try:
                                if elapsed_time_list[j]-end_elapsed_time[j-1]<=1:
                                    pass
                                else:
                                    same_flag=0
                                    displacement=0.0
                                    displacement_time=0.0
                            except:
                                same_flag=0
                                displacement=0.0
                                displacement_time=0.0
                        
                else:
                    speed_list.append(None)
            except:
                speed_list.append(None)

    df['elapsed_time'] = elapsed_time_list

    df['speed'] = speed_list  # m/s
    df['speed'] = 3.6*df['speed'] # km/h
    df = df[columns + ['arclength']+['speed']]

    return df
